﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FP_Tree
{
    public class FPTree
    {
        private Dictionary<String, FPNode> headersTable;
        public Dictionary<String, FPNode> HeadersTable
        {
            get { return headersTable; }
            set { headersTable = value; }
        }
        private FPNode root;
        public FPNode Root
        {
            get { return root; }
            set { root = value; }
        }

        public FPTree()
        {
            headersTable = new Dictionary<string, FPNode>();
            root = new FPNode( null, null, null);
        }

        /*
         * Se asume que una transaccion no tiene items repetidos
         */
        public void addTransaction(List<String> transaction)
        {
            FPNode location = root;
            foreach (String item in transaction)
            {
                if (location.Hijos.ContainsKey(item))
                {
                    location = location.Hijos[item];
                    location.Conteo++;
                }
                else
                {
                    FPNode temp = null;
                    if (headersTable.ContainsKey(item))
                    {
                        temp = new FPNode(item, headersTable[item], location);
                    }
                    else
                    {
                        temp = new FPNode(item, null, location);
                    }
                    location.Hijos[item] = temp;
                    headersTable[item] = temp;
                    location = temp;
                    location.Conteo++;
                }

            }
        }

        public FPNode primerNodo(string item)
        {
            FPNode op = null;
            if (headersTable.ContainsKey(item))
                headersTable.TryGetValue(item, out op);
            return op;

        }

        public FPNode addNodo(FPNode padre,String contenido, int cuenta )
        {
            if (padre == null)
            {
                FPNode fp = new FPNode(null, null, null);
                return fp;
            }
            else
            {
                FPNode fp = new FPNode(padre, contenido, cuenta);
                headersTable.Add(contenido, fp);
                return fp;
            }
        }

//      public void generarNodos(FPNode padre, int profundidad,int[][] datos){
//    while(hayDatos(rango)){
//        (nuevo_rango, item)= buscar(profundidad, rango, datos);
//        nNodo=crearNodo(padre,item,rango.size());
//        generarNodos(nNodo,profundidad+1,nuevo_rango,datos);
//    }
//}

//        public FPNode crearNodo(FPNode padre, String item, int conteo)
//        {
//            nodo = new FPNode(padre, item, conteo);
//            lista[item].ultimo().sgte = nodo;
//        }

        public FPTree podar(String item, FPTree original)
        {
            FPTree resultado = new FPTree();
            for (FPNode nodo = original.primerNodo(item); item != null; nodo = nodo.Siguiente)
            {
                colgarRama(nodo.Padre, nodo.Conteo, resultado);
            }
            return resultado;
        }

        public FPNode colgarRama(FPNode nodo, int cuenta, FPTree resultado)
        {
            if (nodo == null)
            {
                return nodo;
            }
            FPNode padre = colgarRama(nodo.Padre, cuenta, resultado);

            return resultado.addNodo(padre, nodo.Contenido, cuenta);//(padre, nodo.id, nodo.Contenido, cuenta);
        }

        public ICollection<FPNode> getValoresTabla()
        {
            return headersTable.Values;
        }

    }
}
